<!--
 * @Author: Bobby
 * @Date: 2021-12-30 10:01:42
 * @LastEditTime: 2022-03-22 14:43:01
 * @LastEditors: Bobby
 * @Description:
 * @FilePath: \wms-v2\src\ve\elements\basic\uiFullcalendar\uiFullcalendar.vue
 * CIMC-V2
-->
<template>
  <div class="w-full overflow-auto text-black">
    <!-- 时间选择区域 -->
    <div>
      <!-- 图例区域 -->
      <div>
        <div v-for="(item, index) in legendList" :key="index" class="flex">
          <p
            class="rounded-sm mb-0.5"
            :style="{
              width: '20px',
              height: '10px',
              background: item.color,
            }"
          ></p>
          <p class="ml-1 mr-3 text-[12px]">{{ item.legendName }}</p>
        </div>
      </div>
      <!-- 月份选择 -->
      <div class="flex justify-center">
        <div class="flex items-center">
          <div class="cursor-pointer w-[22px] h-[22px] rounded-full bg-gray-400 text-white text-center leading-[22px]" @click="monthChange('left')">
            <vui-icon icon="arrow-left-s-line" />
          </div>
          <div class="text-xl font-medium mx-2">
            {{ `${currentMonth.split('-')[0]}${translateTitle('Ve.elements.年')}${currentMonth.split('-')[1]}${translateTitle('Ve.elements.月')}` }}
          </div>
          <div class="cursor-pointer w-[22px] h-[22px] rounded-full bg-gray-400 text-white text-center leading-[22px]" @click="monthChange('right')">
            <vui-icon icon="arrow-right-s-line" />
          </div>
        </div>
      </div>
      <!-- 日期选择 -->
      <div class="flex my-3">
        <span
          v-for="item in currentMonthDays"
          :key="item"
          class="cursor-pointer w-[28px] h-[24px] bg-gray-100 text-center border border-gray-800 leading-[24px]"
          :class="item == currentDay ? 'bg-green-500 text-white' : ''"
          @click="dayChange(item)"
        >
          {{ item }}
        </span>
      </div>
    </div>
    <div class="w-full overflow-auto">
      <table id="tableId" class="border border-gray-300 select-none border-collapse">
        <tr>
          <!-- 渲染头部时间列区域 -->
          <th></th>
          <th v-for="(item, index) in timeList" :key="index" class="border border-gray-300">{{ item }}</th>
        </tr>
        <!-- 渲染分组项目数据 -->
        <tr v-for="item in groupItemList" :key="item.id">
          <td class="border border-gray-300 text-black text-center">{{ item.name }}</td>
          <td v-for="(i, index) in timeList" :key="index" class="border relative border-gray-300">
            <!-- {{ item.name + `_${index + 1}` }}
          <p>{{ dataList[item.name + `_${index + 1}`] }}</p> -->
            <Draggable
              v-model="dataList[item.name + `_${index}`]"
              v-bind="dragOptions"
              :class="item.name + `_${i}`"
              item-key="id"
              @change="draggableChange"
              @end="draggableEnd"
              @start="draggableStart"
            >
              <template #item="{ element }">
                <div class="event-drag" :itemId="element.id" :style="{ marginLeft: `${(element.startTimeDiff * 80) / 0.3}px` }">
                  <el-popover :show-after="500" trigger="hover" :width="400">
                    <template #reference>
                      <div
                        class="flex text-white h-[20px] items-center rounded mb-1.5 relative z-10"
                        :style="{ background: getBackGroundColor(element.state), width: `${(element.timeDiff * 80) / 30}px` }"
                      >
                        <span
                          class="w-[17px] h-[17px] rounded-full bg-blue-100 text-blue-700 flex-none text-center mx-1.5 text-[12px] leading-[17px]"
                        >
                          入
                        </span>
                        <!-- <span>{{ element.startTimeDiff }}</span> -->
                        <span class="truncate">{{ element.title }}</span>
                      </div>
                    </template>
                    <div class="border-gray-800 border">
                      <p class="flex border-b border-gray-800 h-[24px] items-center">
                        <span class="w-[100px] text-right">{{ translateTitle('Ve.elements.供应商') }}</span>
                        <span class="pl-1 border-l border-gray-800 h-full align-middle">四川攀枝花思明药业有限公司</span>
                      </p>
                      <p class="flex border-b border-gray-800 h-[24px] items-center">
                        <span class="w-[100px] text-right">{{ translateTitle('Ve.elements.预约时段') }}</span>
                        <span class="pl-1 border-l border-gray-800 h-full align-middle">
                          {{ `${element.startTime.split(' ')[1]} ~ ${element.endTime.split(' ')[1]}` }}
                        </span>
                      </p>
                      <p class="flex border-b border-gray-800 h-[24px] items-center">
                        <span class="w-[100px] text-right">{{ translateTitle('Ve.elements.预约状态') }}</span>
                        <span class="pl-1 border-l border-gray-800 h-full align-middle">{{ element.timeDiff }}</span>
                      </p>
                      <p class="flex border-b border-gray-800 h-[24px] items-center">
                        <span class="w-[100px] text-right">{{ translateTitle('Ve.elements.车辆类型') }}</span>
                        <span class="pl-1 border-l border-gray-800 h-full align-middle">厢式货车</span>
                      </p>
                      <p class="flex border-b border-gray-800 h-[24px] items-center">
                        <span class="w-[100px] text-right">{{ translateTitle('Ve.elements.车牌号') }}</span>
                        <span class="pl-1 border-l border-gray-800 h-full align-middle">川A123456</span>
                      </p>
                      <p class="flex border-b border-gray-800 h-[24px] items-center">
                        <span class="w-[100px] text-right">{{ translateTitle('Ve.elements.驾驶员') }}</span>
                        <span class="pl-1 border-l border-gray-800 h-full align-middle">司锡铭</span>
                      </p>
                      <div class="flex items-center">
                        <span class="w-[100px] text-right">{{ translateTitle('Ve.elements.数量') }}</span>
                        <div class="pl-1 border-l border-gray-800">
                          <p>
                            <span>{{ translateTitle('Ve.elements.总箱数') }}</span>
                            <span>60 {{ translateTitle('Ve.elements.箱') }}</span>
                          </p>
                          <p>
                            <span>{{ translateTitle('Ve.elements.总重') }}</span>
                            <span>2000 kg</span>
                          </p>
                          <p>
                            <span>{{ translateTitle('Ve.elements.总体积') }}</span>
                            <span>20.33 ㎡</span>
                          </p>
                          <p>
                            <span>{{ translateTitle('Ve.elements.总托盘') }}</span>
                            <span>23 {{ translateTitle('Ve.elements.托') }}</span>
                          </p>
                        </div>
                      </div>
                    </div>
                  </el-popover>
                </div>
              </template>
            </Draggable>
          </td>
        </tr>
      </table>
    </div>
  </div>
</template>
<script>
  import { translateTitle } from '@/utils/i18n'
  import { defineComponent } from 'vue'
  import Draggable from 'vuedraggable'
  import dayjs from 'dayjs'
  import trim from 'lodash/trim'
  import { UiMixin, RefsInjectMixin } from '@ve/mixin'
  export default defineComponent({
    name: 'UiFullcalendar',
    components: { Draggable },
    mixins: [UiMixin, RefsInjectMixin],

    data() {
      return {
        domHeight: 500,
        timeList: [], // 时间列
        groupItemList: [
          {
            name: 'A01',
            id: 'A01',
          },
          {
            name: 'A02',
            id: 'A02',
          },
          {
            name: 'A03',
            id: 'A03',
          },
          {
            name: 'A04',
            id: 'A04',
          },
          {
            name: 'B01',
            id: 'B01',
          },
          {
            name: 'B02',
            id: 'B02',
          },
          {
            name: 'B03',
            id: 'B03',
          },
          {
            name: 'B04',
            id: 'B04',
          },
        ],
        dataList: {},
        currentMonth: '', // 当前月
        currentDay: '', // 当前日
        currentMonthDays: 0, // 当前月天数
      }
    },
    computed: {
      getExtension() {
        return this.info.extension
      },
      dragOptions() {
        return {
          animation: 200,
          group: 'AAAA',
          disabled: false,
          ghostClass: 'ghost',
          handle: '.event-drag',
        }
      },
      getFullDataList() {
        let dataList = []
        Object.keys(this.dataList).forEach((item) => {
          this.dataList[item].forEach((dataItem) => {
            dataList.push(dataItem)
          })
        })
        return dataList
      },
      legendList() {
        return this.info.extension.legend ? this.info.extension.legend.value : []
      },
    },
    created() {
      // 默认展示当前时间
      this.currentMonth = dayjs().format('YYYY-MM')
      this.currentDay = dayjs().format('DD')
      // 查询当前月天数
      this.currentMonthDays = dayjs(this.currentMonth).daysInMonth()
      // 计算时间列个数
      this.getTimeList()
    },
    mounted() {
      this.getTdItemList()
      this.placeDataToTd()
    },
    methods: {
      translateTitle,
      getElementWidth(timeDiff) {
        if (timeDiff >= 1) {
          // 分别取小数位与整数位单独计算
          const a = Math.trunc(timeDiff / 0.6)
          const b = timeDiff % 0.6
          return a * 160 + (b * 80) / 0.3
        } else {
          return (timeDiff * 80) / 0.3
        }
      },
      // 计算时间列
      getTimeList() {
        let startTime = '5a:00'
        let endTime = '19:41'
        let timeList = []
        const startH = Number(startTime.split(':')[0])
        const startM = Number(startTime.split(':')[1])
        const endH = Number(endTime.split(':')[0])
        const endM = Number(endTime.split(':')[1])
        const iTime = endH - startH
        if (iTime && iTime > 0 && !isNaN(startH) && !isNaN(startM) && !isNaN(endH) && !isNaN(endM)) {
          // 判断时间格式是否正确
          for (let i = 0; i < iTime; i++) {
            if (i === 0 && startM >= 30) {
              timeList.push(`${i + startH}:30`)
            } else {
              timeList.push(`${i + startH}:00`)
              timeList.push(`${i + startH}:30`)
            }
            if (i === iTime - 1 && 0 < endM && endM < 30) {
              timeList.push(`${i + startH + 1}:00`)
            } else if (i === iTime - 1 && 30 < endM) {
              timeList.push(`${i + startH + 1}:00`)
              timeList.push(`${i + startH + 1}:30`)
            }
          }
        } else {
          // 如果开始时间与结束时间格式不正确 则渲染默认的时间
          for (let i = 0; i < 12; i++) {
            timeList.push(`${i + 6}:00`)
            timeList.push(`${i + 6}:30`)
          }
        }
        this.timeList = timeList
      },
      // 组织数据格式
      getTdItemList() {
        this.groupItemList.forEach((groupItem) => {
          for (let i = 0; i < this.timeList.length; i++) {
            const keyStr = `${groupItem.id}_${i}`
            // this.dataList.push({
            //   [keyStr]: [],
            // })
            this.dataList[keyStr] = []
          }
        })
      },
      // 将数据放至对应的单元格
      placeDataToTd() {
        // 先模拟数据
        function getRandomInt(max) {
          return Math.floor(Math.random() * max)
        }
        let mockDataList = []
        this.groupItemList.forEach((groupItem) => {
          this.timeList.forEach((timeItem, index) => {
            const num = Math.random()
            if (num > 0.8) {
              let timeItemNum = Number(timeItem.replace(':', '.'))
              const aList = [0, 0.1, 0.2]
              const bList = [0.5, 1, 1.5, 2, 2.5, 3]
              const stateList = ['1', '2', '3', '4']
              const timeItemStr = (timeItemNum + aList[getRandomInt(3)]).toFixed(2).replace('.', ':')
              const endTimeStr = (timeItemNum + bList[getRandomInt(6)]).toFixed(2).replace('.', ':')
              mockDataList.push({
                id: groupItem.name + index,
                title: `XXX_${groupItem.name}_${timeItemStr}_${endTimeStr}`,
                resourceId: groupItem.id,
                startTime: `2022-09-08 ${timeItemStr}`,
                endTime: `2022-09-08 ${endTimeStr}`,
                state: stateList[getRandomInt(4)],
              })
            }
          })
        })
        // 放置数据
        mockDataList.forEach((dataItem) => {
          // 先判断数据属于哪一个单元格
          // 先计算数据的开始时间
          const startTime = dataItem.startTime.split(' ')[1]
          const endTime = dataItem.endTime.split(' ')[1]
          console.log('startTime ------- ', startTime)
          if (startTime && endTime) {
            this.timeList.forEach((timeItem, index) => {
              // 计算时间差并存储
              dataItem.timeDiff = dayjs(dataItem.endTime).diff(dayjs(dataItem.startTime), 'minute')
              // 判断时间是否在当前时间间隔内
              const startTimeNum = Number(startTime.replace(':', '.'))
              const timeItemNum = Number(timeItem.replace(':', '.'))
              if (startTimeNum >= timeItemNum && startTimeNum < timeItemNum + 0.3) {
                // 存储开始时间差，以计算偏移量
                dataItem.startTimeDiff = startTimeNum - timeItemNum
                const dataSourceKey = `${dataItem.resourceId}_${index}`
                this.dataList[dataSourceKey] && this.dataList[dataSourceKey].push(dataItem)
              }
            })
          }
        })
      },
      draggableChange(event) {
        console.log('event ---------- draggableChange', event)
      },
      draggableStart(event) {
        console.log('event ---------- draggableStart', event)
      },
      //拖动结束
      draggableEnd(event) {
        console.log('event ---------- draggableEnd', event)
        const itemId = event.item._underlying_vm_.id
        const dataItem = this.getFullDataList.filter((item) => {
          return item.id === itemId
        })[0]
        const fromGroup = event.from.className
        const toGroup = event.to.className
        if (fromGroup !== toGroup) {
          const [formGroupId, fromTimeCol] = fromGroup.split('_')
          const [toGroupId, toTimeCol] = toGroup.split('_')
          if (formGroupId !== toGroupId) {
            dataItem.resourceId = toGroupId
          }
          if (fromTimeCol !== toTimeCol) {
            dataItem.startTime = dataItem.startTime.split(' ')[0] + ' ' + toTimeCol
            dataItem.startTimeDiff = 0
            // 计算结束时间
            dataItem.endTime = dayjs(dataItem.startTime).add(dataItem.timeDiff, 'minute').format('YYYY-MM-DD HH:mm')
          }
        }
        console.log('dataItem ---------- ', dataItem)
      },
      // 月份切换
      monthChange(flag) {
        if (flag === 'left') {
          // 查找前一个月
          this.currentMonth = dayjs(this.currentMonth)
            .month(dayjs(this.currentMonth).month() - 1)
            .format('YYYY-MM')
        } else if (flag === 'right') {
          // 查找后一个月
          this.currentMonth = dayjs(this.currentMonth)
            .month(dayjs(this.currentMonth).month() + 1)
            .format('YYYY-MM')
        }
        // 获取当月天数
        this.currentMonthDays = dayjs(this.currentMonth).daysInMonth()
      },
      // 日切换
      dayChange(day) {
        if (this.currentDay != day) {
          this.currentDay = day
        }
      },
      getBackGroundColor(status) {
        let color = ''
        this.getExtension.legend.value.forEach((item) => {
          // 如果值里面有 ，则代表为多指匹配同一个图例
          if (item.legendValue.indexOf(',') > -1) {
            let legendValueList = item.legendValue.split(',')
            legendValueList.forEach((legendValueItem) => {
              if (trim(legendValueItem) === status) {
                color = item.color
              }
            })
          } else {
            if (item.legendValue === status) {
              color = item.color
            }
          }
        })
        return color || 'royalblue'
      },
    },
  })
</script>
<style lang="scss" scoped>
  td {
    // width: 20%;
    height: 30px;
    overflow: visible;
    // border-bottom: 1px solid black;
    // border-right: 1px solid black;
    cursor: default;
    color: #999;
  }

  th {
    width: 80px;
    height: 20px;
    color: #000;
    // font-size: 12px;
    // font-weight: normal;
    // border-bottom: 2px solid black;
  }

  table {
    // border: 1px solid black;
    font-size: 13px;
    table-layout: fixed;
    width: 100%;
    // overflow: auto;
  }
</style>
